﻿/*
 * @Author       : xiaoyuan-cloud 1805980417@qq.com
 * @Date         : 2024-10-21 09:48:51
 * @LastEditors  : xiaoyuan-cloud 1805980417@qq.com
 * @LastEditTime : 2024-12-02 08:58:34
 * @FilePath     : \charger_controller\packages\SAE_J1939\src\J1939_config.c
 * @Description  : SAE_J1939协议栈底层接口配置
 * SPDX-License-Identifier: MIT
 * Copyright (c) 2024 by xiaoyuan-cloud, All Rights Reserved.
 */
#include "j1939_config.h"
#include "string.h"
#include "bsp_can.h"

 /*CAN回调数据缓存*/
typedef struct
{
    j1939_uint8_t buf[8];	// 数据缓冲区
    j1939_uint32_t buf_len; // 数据长度
    j1939_uint32_t id;		// 报文ID

    j1939_uint8_t flag; // 接收数据标志
} CAN_DATA;

/*4路CAN通信接收数据*/
CAN_DATA can1_data; // CAN1报文数据
CAN_DATA can2_data; // CAN2报文数据
CAN_DATA can3_data; // CAN3报文数据
CAN_DATA can4_data; // CAN4报文数据

/*CAN底层接口*/
CAN_PORT_FUNC can_port_func;

/**
 * @brief: CAN1接收回调处理函数
 * @param {j1939_uint32_t} id 报文ID
 * @param {j1939_uint8_t*} buf 数据
 * @param {j1939_uint32_t} buf_len 数据长度
 * @return {*}NULL
 */
static void J1939_CAN1_RX_Callback(const j1939_uint32_t id, const j1939_uint8_t* buf, const j1939_uint32_t buf_len)
{
    can1_data.flag = 1;

    /*转存数据*/
    can1_data.id = id;
    memcpy(can1_data.buf, buf, buf_len);
    can1_data.buf_len = buf_len;

    J1939_ISR(Select_CAN_NODE_1);
    J1939_TP_Poll(Select_CAN_NODE_1, 1);
}

/**
 * @brief: CAN2接收回调处理函数
 * @param {j1939_uint32_t} id 报文ID
 * @param {j1939_uint8_t*} buf 数据
 * @param {j1939_uint32_t} buf_len 数据长度
 * @return {*}NULL
 */
static void J1939_CAN2_RX_Callback(const j1939_uint32_t id, const j1939_uint8_t* buf, const j1939_uint32_t buf_len)
{
    can2_data.flag = 1;

    /*转存数据*/
    can2_data.id = id;
    memcpy(can2_data.buf, buf, buf_len);
    can2_data.buf_len = buf_len;

    J1939_ISR(Select_CAN_NODE_2);
    J1939_TP_Poll(Select_CAN_NODE_1, 1);
}

/**
 * @brief: CAN3接收回调处理函数
 * @param {j1939_uint32_t} id 报文ID
 * @param {j1939_uint8_t*} buf 数据
 * @param {j1939_uint32_t} buf_len 数据长度
 * @return {*}NULL
 */
static void J1939_CAN3_RX_Callback(const j1939_uint32_t id, const j1939_uint8_t* buf, const j1939_uint32_t buf_len)
{
    can3_data.flag = 1;

    /*转存数据*/
    can3_data.id = id;
    memcpy(can3_data.buf, buf, buf_len);
    can3_data.buf_len = buf_len;

    J1939_ISR(Select_CAN_NODE_3);
}

/**
 * @brief: CAN4接收回调处理函数
 * @param {j1939_uint32_t} id 报文ID
 * @param {j1939_uint8_t*} buf 数据
 * @param {j1939_uint32_t} buf_len 数据长度
 * @return {*}NULL
 */
static void J1939_CAN4_RX_Callback(const j1939_uint32_t id, const j1939_uint8_t* buf, const j1939_uint32_t buf_len)
{
    can4_data.flag = 1;

    /*转存数据*/
    can4_data.id = id;
    memcpy(can4_data.buf, buf, buf_len);
    can4_data.buf_len = buf_len;

    J1939_ISR(Select_CAN_NODE_4);
}

/**
 * @brief J1939协议栈CAN接收回调添加
 * @return {*}
 */
void J1939_CAN_AddCallback(void)
{
    can_port_func.can_add_rx_callback(Select_CAN_NODE_1, J1939_CAN1_RX_Callback);
    can_port_func.can_add_rx_callback(Select_CAN_NODE_2, J1939_CAN2_RX_Callback);
    can_port_func.can_add_rx_callback(Select_CAN_NODE_3, J1939_CAN3_RX_Callback);
    can_port_func.can_add_rx_callback(Select_CAN_NODE_4, J1939_CAN4_RX_Callback);
}

/**
 * @brief SAE_J1939协议栈底层接口初始化
 * @param {*can_send_data} CAN发送报文接口
 * @param {*can_add_rx_callback} CAN接收报文回调接口
 * @return {*}
 */
void J1939_Config_Init(int (*can_send_data)(CAN_NODE can_port, j1939_uint8_t* pbuf, j1939_uint32_t buf_len, j1939_uint32_t ExdID),
    int (*can_add_rx_callback)(CAN_NODE can_port, void (*pCallbacks)(const j1939_uint32_t id, const j1939_uint8_t* buf, const j1939_uint32_t buflen)))
{
    /*初始化J1939*/
    J1939_Init();

    /*接口函数指针*/
    can_port_func.can_send_data = can_send_data;
    can_port_func.can_add_rx_callback = can_add_rx_callback;

    /*添加回调*/
    J1939_CAN_AddCallback();
}

/**
 * @brief CAN发送报文(协议栈使用接口)
 * @param {CAN_NODE} port   CAN端口
 * @param {J1939_MESSAGE*} pthis 消息对象
 * @return {*}
 * @retval 0: 发送成功
 * @retval -1: 发送失败
 */
int J1939_CAN_Transmit(CAN_NODE port, const J1939_MESSAGE* pthis)
{
    j1939_int32_t tx_id;
    j1939_uint8_t tx_data[8] = { 0 };

    /*计算报文ID*/
    tx_id = (pthis->j1939_pid.SourceAddress) + ((pthis->j1939_pid.PDUSpecific) << 8) + ((pthis->j1939_pid.PDUFormat) << 16) +
        ((((pthis->j1939_pid.Priority) << 2) + ((pthis->j1939_pid.Res) << 1) + (pthis->j1939_pid.DataPage)) << 24);
    /*转存报文数据*/
    memcpy(tx_data, pthis->j1939_pid.Data, pthis->j1939_pid.DataLength);
    /*发送报文*/
    return can_port_func.can_send_data(port, tx_data, pthis->j1939_pid.DataLength, tx_id);
}

/**
 * @brief CAN读取报文(协议栈使用接口)
 * @param {CAN_NODE} port   CAN端口
 * @param {J1939_MESSAGE} *pthis    消息对象
 * @return {*}
 * @retval 0: 读取成功
 * @retval -1: 读取失败
 */
int J1939_CAN_Receive(CAN_NODE port, J1939_MESSAGE* pthis)
{
    switch (port)
    {
    case Select_CAN_NODE_1:
    {
        if (can1_data.flag == 1)
        {
            // CAN1报文转存
            memcpy(pthis->j1939_pid.Data, can1_data.buf, can1_data.buf_len);
            pthis->j1939_pid.DataLength = can1_data.buf_len;
            pthis->j1939_pid.DataPage = can1_data.id >> 24 & 1;
            pthis->j1939_pid.PDUFormat = can1_data.id >> 16 & 0xff;
            pthis->j1939_pid.PDUSpecific = can1_data.id >> 8 & 0xff;
            pthis->j1939_pid.SourceAddress = can1_data.id & 0xff;

            // 清除标志
            can1_data.flag = 0;
            return 0;
        }

        return -1;
        break;
    }
    case Select_CAN_NODE_2:
    {
        if (can2_data.flag == 1)
        {
            // CAN2报文转存
            memcpy(pthis->j1939_pid.Data, can2_data.buf, can2_data.buf_len);
            pthis->j1939_pid.DataLength = can2_data.buf_len;
            pthis->j1939_pid.DataPage = can2_data.id >> 24 & 1;
            pthis->j1939_pid.PDUFormat = can2_data.id >> 16 & 0xff;
            pthis->j1939_pid.PDUSpecific = can2_data.id >> 8 & 0xff;
            pthis->j1939_pid.SourceAddress = can2_data.id & 0xff;

            // 清除标志
            can2_data.flag = 0;
            return 0;
        }

        return -1;
        break;
    }
    case Select_CAN_NODE_3:
    {
        if (can3_data.flag == 1)
        {
            // CAN3报文转存
            memcpy(pthis->j1939_pid.Data, can3_data.buf, can3_data.buf_len);
            pthis->j1939_pid.DataLength = can3_data.buf_len;
            pthis->j1939_pid.DataPage = can3_data.id >> 24 & 1;
            pthis->j1939_pid.PDUFormat = can3_data.id >> 16 & 0xff;
            pthis->j1939_pid.PDUSpecific = can3_data.id >> 8 & 0xff;
            pthis->j1939_pid.SourceAddress = can3_data.id & 0xff;

            // 清除标志
            can3_data.flag = 0;
            return 0;
        }

        return -1;
        break;
    }
    case Select_CAN_NODE_4:
    {
        if (can4_data.flag == 1)
        {
            // CAN4报文转存
            memcpy(pthis->j1939_pid.Data, can4_data.buf, can4_data.buf_len);
            pthis->j1939_pid.DataLength = can4_data.buf_len;
            pthis->j1939_pid.DataPage = can4_data.id >> 24 & 1;
            pthis->j1939_pid.PDUFormat = can4_data.id >> 16 & 0xff;
            pthis->j1939_pid.PDUSpecific = can4_data.id >> 8 & 0xff;
            pthis->j1939_pid.SourceAddress = can4_data.id & 0xff;

            // 标志转存
            can4_data.flag = 0;
            return 0;
        }

        return -1;
        break;
    }
    default:
        return -1;
        break;
    }
}
